package com.lz.yz.member.service.impl;

import com.lz.yz.base.entity.ReturnValue;
import com.lz.yz.base.util.Constant;
import com.lz.yz.base.util.StringUtil;
import com.lz.yz.core.AbstractService;
import com.lz.yz.member.dao.LableMapper;
import com.lz.yz.member.dao.MemberMapper;
import com.lz.yz.member.dao.PropertyInfoMapper;
import com.lz.yz.member.dao.UserLableMapper;
import com.lz.yz.member.entity.*;
import com.lz.yz.member.enumeration.AccountField;
import com.lz.yz.member.enumeration.AccountType;
import com.lz.yz.member.enumeration.LabelType;
import com.lz.yz.member.model.*;
import com.lz.yz.member.param.MemberParam;
import com.lz.yz.member.service.AccountService;
import com.lz.yz.member.service.MemberService;
import com.lz.yz.outing.enumeration.PlatformType;
import com.lz.yz.outing.service.PushService;
import com.lz.yz.outing.service.SyncLockService;
import com.lz.yz.outing.service.WechatService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;


/**
 * Created by CodeGenerator on 2017/11/09.
 */
@Service
@Transactional
public class MemberServiceImpl extends AbstractService<Member> implements MemberService {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    MemberMapper memberMapper;

    @Autowired
    SyncLockService syncLockService;

    @Autowired
    AccountService accountService;

    @Autowired
    PropertyInfoMapper propertyInfoMapper;

    @Autowired
    WechatService wechatService;

    @Autowired
    LableMapper lableMapper;

    @Autowired
    UserLableMapper userLableMapper;

    @Autowired
    PushService pushService;

    @Resource(name = "redisTemplate")
    RedisTemplate<String, Integer> redisTemplate;

    /**
     * 用户注册
     */
    @Override
    public ReturnValue validateAndRegist(ThirdLoginModel user) {

        String code = user.getCode();
        Integer platform = user.getPlatform()==null? PlatformType.MP.value():PlatformType.getPlatformTypeByStatus(user.getPlatform()).value();
        //获取微信用户信息
        Member resultInfo= wechatService.getUserInfoByCode(platform,code);
        if(resultInfo == null){
            return ReturnValue.generateFalseReturnValue("获取微信用户信息失败");
        }
        String openId = resultInfo.getOpenId();
        String unionId = resultInfo.getUnionId();
        try {
            Account loginAccount;
            loginAccount = accountService.getAccountByField(AccountField.UnionId, unionId, AccountType.Internal.value()+"");
            if(loginAccount!=null){ //UnionId存在直接登录成功 不存在走注册流程

                if(platform.equals(PlatformType.MP.value())){
                    //绑定openid
                    if(loginAccount.getWechatToken()==null){
                        Account update = new Account();
                        update.setId(loginAccount.getId());
                        update.setWechatToken(openId);
                        accountService.updateByIdSelective(update);
                    }
                }

                if(platform.equals(PlatformType.KF.value())){
                    //pc端登陆记住登陆状态
                    ValueOperations<String, Integer> ops = redisTemplate.opsForValue();
                    if(ops.get(Constant.PC_LOGIN_KEY+loginAccount.getId())==null){
                        ops.set(Constant.PC_LOGIN_KEY+loginAccount.getId(),1,1, TimeUnit.HOURS);
                    }
                    pushService.push(""+loginAccount.getId(),"欢迎"+resultInfo.getRealName()+"登陆");
                }
                ResponseAccount model = new ResponseAccount(loginAccount.getId());
                BeanUtils.copyProperties(loginAccount, model);
                model.setHeadPortrait(resultInfo.getHeadPortrait());
                return ReturnValue.generateTrueReturnValue(model);
            }

            // check double click
            if (syncLockService.syncLock("register/" + openId, 1, TimeUnit.SECONDS)) {
                Account account = new Account();
                account.setType(AccountType.Internal.value());
                //过滤openId
                if(platform.equals(PlatformType.KF.value())){
                    account.setWechatToken(null);
                }else {
                    account.setWechatToken(openId);
                }
                account.setUnionId(unionId);
                //add account
                int accountId = accountService.addNewAccount(account);
                loginAccount = accountService.doLogin(AccountField.UnionId, unionId, null, account.getType() + "");

                Member userInfo = new Member();
                BeanUtils.copyProperties(resultInfo,userInfo);
                userInfo.setAccountId(accountId);
                userInfo.setRealName(StringUtil.filterEmoji(userInfo.getRealName()));
                //add user info
                int addUser = memberMapper.insertSelective(userInfo);
                if (addUser > 0) {
                    PropertyInfo propertyInfo=new PropertyInfo();
                    propertyInfo.setAccountId(loginAccount.getId());
                    int addProperty = propertyInfoMapper.insertSelective(propertyInfo);
                    if(addProperty>0){
                        //初始化用户标签
                        List<UserLable> userLables=new ArrayList<>();
                        List<Lable> lableList = lableMapper.select(new Lable(1));
                        lableList.forEach(lable -> {
                            UserLable userLable=new UserLable();
                            userLable.setLableId(lable.getId());
                            userLable.setAccountId(accountId);
                            userLable.setType(LabelType.INIT.value());
                            userLable.setCreatedAt(new Date());
                            userLables.add(userLable);
                        });
                        userLableMapper.insertList(userLables);
                    }
                }

                if(platform.equals(PlatformType.KF.value())){
                    //pc端登陆记住登陆状态
                    ValueOperations<String, Integer> ops = redisTemplate.opsForValue();
                    if(ops.get("login:"+loginAccount.getId())==null){
                        ops.set("login:"+loginAccount.getId(),1,1, TimeUnit.HOURS);
                    }
                }
                ResponseAccount model = new ResponseAccount(loginAccount.getId());
                BeanUtils.copyProperties(loginAccount, model);
                model.setHeadPortrait(resultInfo.getHeadPortrait());
                return ReturnValue.generateTrueReturnValue(model);
            } else {
                return ReturnValue.generateFalseReturnValue("请不要重复提交");
            }
        } catch (Exception e) {
            logger.error("注册用户失败，异常为{}, 失败的openid为{} ", e, openId);
            return ReturnValue.generateFalseReturnValue("注册用户失败！");
        }
    }



    /**
     * 验证手机号是否注册
     *
     * @param phone
     * @return true已注册 false未注册
     */
    @Override
    public Boolean validateAccount(String phone) {
        return accountService.getAccountByField(AccountField.Name,phone, AccountType.Internal.value()+"")!=null;
    }

    /**
     * 获取用户个人信息
     */
    @Override
    public ReturnValue getUserInfo(MemberParam param) {
        MemberModel memberModel = memberMapper.selectMemberInfoById(param);
        if(memberModel==null){
            return ReturnValue.generateFalseReturnValue("用户不存在!");
        }
        memberModel.setBeanList(memberMapper.selectMemberLableById(param));
        //判断是否完善过资料
        memberModel.setIsIntact(this.validateAccountIntact(param.getAccountId())?1:0);
        return ReturnValue.generateTrueReturnValue(memberModel);
    }

    /**
     * 获取他人用户个人信息
     */
    @Override
    public ReturnValue getOtherUserInfo(MemberParam param) {
        MemberModel memberModel = memberMapper.selectMemberInfoById(param);
        if(memberModel==null){
            return ReturnValue.generateFalseReturnValue("用户不存在!");
        }
        return ReturnValue.generateTrueReturnValue(memberModel);
    }



    /**
     * 修改个人标签信息
     *
     */
    @Override
    public void updateUser(RequestMemberModel model) {
        Member update =new Member();
        BeanUtils.copyProperties(model, update);
        update.setId(model.getMemberId());
        this.update(update);


        if(model.getLabelIds()!=null&&!model.getLabelIds().equals("")){  //修改用户标签逻辑
            MemberLableModel memberLableModel=new MemberLableModel();
            memberLableModel.setLableIds(model.getLabelIds());
            memberLableModel.setAccountId(model.getAccountId());

            UserLable userLable=new UserLable();
            userLable.setAccountId(memberLableModel.getAccountId());
            userLable.setType(LabelType.SELECT.value());
            userLableMapper.delete(userLable);

            List<UserLable> userLables=new ArrayList<>();
            String ids = memberLableModel.getLableIds();
            String[] idArr = ids.split(",");
            for (String id : idArr) {
                UserLable userLable1=new UserLable();
                userLable1.setAccountId(model.getAccountId());
                userLable1.setType(LabelType.SELECT.value());
                userLable1.setLableId(Integer.valueOf(id));
                userLables.add(userLable1);
            }
            userLableMapper.insertList(userLables);
        }

    }

    /**
     * 验证账户有没有完善资料
     * @return true完善 false未完善
     */
    @Override
    public Boolean validateAccountIntact(Integer accountId) {
        Member member = this.findBy("accountId",accountId);
        return !(member.getPhone()==null||member.getCompanyName()==null||member.getPosition()==null||member.getRealName()==null);
    }
}
